using McpApi.Models;
using System.Text.Json;
using System.Web;

namespace McpApi.Services
{
    /// <summary>
    /// 天气服务 - 集成OpenWeatherMap API
    /// </summary>
    public class WeatherService
    {
        private readonly ILogger<WeatherService> _logger;
        private readonly HttpClient _httpClient;
        private readonly IConfiguration _configuration;
        private readonly JsonSerializerOptions _jsonOptions;

        // 缓存
        private readonly Dictionary<string, (DateTime expiry, object data)> _cache = new();
        private readonly object _cacheLock = new object();

        public WeatherService(ILogger<WeatherService> logger, HttpClient httpClient, IConfiguration configuration)
        {
            _logger = logger;
            _httpClient = httpClient;
            _configuration = configuration;

            _jsonOptions = new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                WriteIndented = true
            };

            // 配置HTTP客户端
            var baseUrl = _configuration["WeatherAPI:BaseUrl"] ?? "https://api.openweathermap.org/data/2.5";
            _httpClient.BaseAddress = new Uri(baseUrl);
            _httpClient.Timeout = TimeSpan.FromSeconds(30);
        }

        /// <summary>
        /// 获取当前天气
        /// </summary>
        public async Task<MESToolResult> GetCurrentWeatherAsync(Dictionary<string, object> parameters)
        {
            try
            {
                var city = parameters.GetValueOrDefault("city")?.ToString() ?? 
                          _configuration["WeatherAPI:DefaultCity"] ?? "Beijing";
                var countryCode = parameters.GetValueOrDefault("countryCode")?.ToString() ?? 
                                 _configuration["WeatherAPI:DefaultCountryCode"] ?? "CN";

                _logger.LogInformation("获取当前天气: {City}, {Country}", city, countryCode);

                // 检查缓存
                var cacheKey = $"current_{city}_{countryCode}";
                if (TryGetFromCache<SimpleWeatherInfo>(cacheKey, out var cachedWeather))
                {
                    _logger.LogDebug("从缓存获取天气数据");
                    return new MESToolResult
                    {
                        Success = true,
                        Message = "获取当前天气成功（缓存）",
                        Data = cachedWeather
                    };
                }

                var apiKey = _configuration["WeatherAPI:ApiKey"];
                if (string.IsNullOrEmpty(apiKey) || apiKey == "YOUR_OPENWEATHER_API_KEY")
                {
                    // 返回模拟数据
                    var mockWeather = GenerateMockCurrentWeather(city);
                    SetCache(cacheKey, mockWeather);
                    
                    return new MESToolResult
                    {
                        Success = true,
                        Message = "获取当前天气成功（模拟数据）",
                        Data = mockWeather
                    };
                }

                // 调用真实API
                var units = _configuration["WeatherAPI:Units"] ?? "metric";
                var lang = _configuration["WeatherAPI:Language"] ?? "zh_cn";
                var url = $"/weather?q={HttpUtility.UrlEncode(city)},{countryCode}&appid={apiKey}&units={units}&lang={lang}";

                var response = await _httpClient.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    var jsonContent = await response.Content.ReadAsStringAsync();
                    var weatherResponse = JsonSerializer.Deserialize<CurrentWeatherResponse>(jsonContent, _jsonOptions);
                    
                    if (weatherResponse != null)
                    {
                        var simpleWeather = ConvertToSimpleWeather(weatherResponse);
                        SetCache(cacheKey, simpleWeather);
                        
                        _logger.LogInformation("成功获取天气数据: {Temp}°C, {Condition}", 
                            simpleWeather.Temperature, simpleWeather.Condition);

                        return new MESToolResult
                        {
                            Success = true,
                            Message = "获取当前天气成功",
                            Data = simpleWeather
                        };
                    }
                }

                _logger.LogWarning("天气API调用失败，状态码: {StatusCode}", response.StatusCode);
                var fallbackWeather = GenerateMockCurrentWeather(city);
                return new MESToolResult
                {
                    Success = true,
                    Message = "获取当前天气成功（备用数据）",
                    Data = fallbackWeather
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取当前天气失败");
                return new MESToolResult
                {
                    Success = false,
                    Message = $"获取天气失败: {ex.Message}",
                    ErrorCode = "WEATHER_ERROR"
                };
            }
        }

        /// <summary>
        /// 获取天气预报
        /// </summary>
        public async Task<MESToolResult> GetWeatherForecastAsync(Dictionary<string, object> parameters)
        {
            try
            {
                var city = parameters.GetValueOrDefault("city")?.ToString() ?? 
                          _configuration["WeatherAPI:DefaultCity"] ?? "Beijing";
                var countryCode = parameters.GetValueOrDefault("countryCode")?.ToString() ?? 
                                 _configuration["WeatherAPI:DefaultCountryCode"] ?? "CN";
                var days = int.Parse(parameters.GetValueOrDefault("days")?.ToString() ?? "5");

                _logger.LogInformation("获取天气预报: {City}, {Country}, {Days}天", city, countryCode, days);

                // 检查缓存
                var cacheKey = $"forecast_{city}_{countryCode}_{days}";
                if (TryGetFromCache<List<SimpleWeatherInfo>>(cacheKey, out var cachedForecast))
                {
                    return new MESToolResult
                    {
                        Success = true,
                        Message = "获取天气预报成功（缓存）",
                        Data = cachedForecast
                    };
                }

                var apiKey = _configuration["WeatherAPI:ApiKey"];
                if (string.IsNullOrEmpty(apiKey) || apiKey == "YOUR_OPENWEATHER_API_KEY")
                {
                    // 返回模拟数据
                    var mockForecast = GenerateMockForecast(city, days);
                    SetCache(cacheKey, mockForecast);
                    
                    return new MESToolResult
                    {
                        Success = true,
                        Message = "获取天气预报成功（模拟数据）",
                        Data = mockForecast
                    };
                }

                // 调用真实API
                var units = _configuration["WeatherAPI:Units"] ?? "metric";
                var lang = _configuration["WeatherAPI:Language"] ?? "zh_cn";
                var cnt = Math.Min(days * 8, 40); // API最多返回5天，每天8个时间点
                var url = $"/forecast?q={HttpUtility.UrlEncode(city)},{countryCode}&appid={apiKey}&units={units}&lang={lang}&cnt={cnt}";

                var response = await _httpClient.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    var jsonContent = await response.Content.ReadAsStringAsync();
                    var forecastResponse = JsonSerializer.Deserialize<WeatherForecastResponse>(jsonContent, _jsonOptions);
                    
                    if (forecastResponse != null)
                    {
                        var simpleForecast = ConvertToSimpleForecast(forecastResponse);
                        SetCache(cacheKey, simpleForecast);
                        
                        return new MESToolResult
                        {
                            Success = true,
                            Message = "获取天气预报成功",
                            Data = simpleForecast
                        };
                    }
                }

                _logger.LogWarning("天气预报API调用失败，状态码: {StatusCode}", response.StatusCode);
                var fallbackForecast = GenerateMockForecast(city, days);
                return new MESToolResult
                {
                    Success = true,
                    Message = "获取天气预报成功（备用数据）",
                    Data = fallbackForecast
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取天气预报失败");
                return new MESToolResult
                {
                    Success = false,
                    Message = $"获取天气预报失败: {ex.Message}",
                    ErrorCode = "FORECAST_ERROR"
                };
            }
        }

        /// <summary>
        /// 检查恶劣天气预警
        /// </summary>
        public async Task<MESToolResult> CheckWeatherAlertsAsync(Dictionary<string, object> parameters)
        {
            try
            {
                var city = parameters.GetValueOrDefault("city")?.ToString() ?? 
                          _configuration["WeatherAPI:DefaultCity"] ?? "Beijing";

                _logger.LogInformation("检查天气预警: {City}", city);

                // 获取当前天气和预报
                var currentResult = await GetCurrentWeatherAsync(parameters);
                var forecastResult = await GetWeatherForecastAsync(parameters);

                var alerts = new List<WeatherAlert>();

                if (currentResult.Success && currentResult.Data is SimpleWeatherInfo current)
                {
                    alerts.AddRange(AnalyzeCurrentWeatherAlerts(current));
                }

                if (forecastResult.Success && forecastResult.Data is List<SimpleWeatherInfo> forecast)
                {
                    alerts.AddRange(AnalyzeForecastAlerts(forecast));
                }

                return new MESToolResult
                {
                    Success = true,
                    Message = $"检查天气预警完成，发现 {alerts.Count} 个预警",
                    Data = alerts
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查天气预警失败");
                return new MESToolResult
                {
                    Success = false,
                    Message = $"检查天气预警失败: {ex.Message}",
                    ErrorCode = "ALERT_ERROR"
                };
            }
        }

        #region 私有方法

        /// <summary>
        /// 缓存操作
        /// </summary>
        private bool TryGetFromCache<T>(string key, out T? value)
        {
            lock (_cacheLock)
            {
                if (_cache.TryGetValue(key, out var cached) && cached.expiry > DateTime.UtcNow)
                {
                    value = (T)cached.data;
                    return true;
                }
                value = default;
                return false;
            }
        }

        private void SetCache(string key, object value)
        {
            lock (_cacheLock)
            {
                var expiryMinutes = int.Parse(_configuration["WeatherAPI:CacheExpiryMinutes"] ?? "10");
                _cache[key] = (DateTime.UtcNow.AddMinutes(expiryMinutes), value);
            }
        }

        /// <summary>
        /// 转换为简化天气信息
        /// </summary>
        private SimpleWeatherInfo ConvertToSimpleWeather(CurrentWeatherResponse response)
        {
            var weather = response.Weather.FirstOrDefault();
            return new SimpleWeatherInfo
            {
                Location = response.Name,
                DateTime = DateTimeOffset.FromUnixTimeSeconds(response.Dt).DateTime,
                Temperature = response.Main?.Temp ?? 0,
                FeelsLike = response.Main?.FeelsLike ?? 0,
                Humidity = response.Main?.Humidity ?? 0,
                Condition = weather?.Main ?? "Unknown",
                Description = weather?.Description ?? "未知",
                WindSpeed = response.Wind?.Speed ?? 0,
                WindDirection = response.Wind?.Deg ?? 0,
                Visibility = response.Visibility,
                AlertLevel = DetermineAlertLevel(response)
            };
        }

        private List<SimpleWeatherInfo> ConvertToSimpleForecast(WeatherForecastResponse response)
        {
            return response.List.Select(item =>
            {
                var weather = item.Weather.FirstOrDefault();
                return new SimpleWeatherInfo
                {
                    Location = response.City?.Name ?? "Unknown",
                    DateTime = DateTimeOffset.FromUnixTimeSeconds(item.Dt).DateTime,
                    Temperature = item.Main?.Temp ?? 0,
                    FeelsLike = item.Main?.FeelsLike ?? 0,
                    Humidity = item.Main?.Humidity ?? 0,
                    Condition = weather?.Main ?? "Unknown",
                    Description = weather?.Description ?? "未知",
                    WindSpeed = item.Wind?.Speed ?? 0,
                    WindDirection = item.Wind?.Deg ?? 0,
                    Precipitation = item.Pop,
                    Visibility = item.Visibility
                };
            }).ToList();
        }

        /// <summary>
        /// 生成模拟天气数据
        /// </summary>
        private SimpleWeatherInfo GenerateMockCurrentWeather(string city)
        {
            var random = new Random();
            var conditions = new[] { "Clear", "Clouds", "Rain", "Snow", "Fog" };
            var descriptions = new[] { "晴朗", "多云", "小雨", "雪", "雾" };
            
            var conditionIndex = random.Next(conditions.Length);
            
            return new SimpleWeatherInfo
            {
                Location = city,
                DateTime = DateTime.UtcNow,
                Temperature = random.Next(-10, 35),
                FeelsLike = random.Next(-15, 40),
                Humidity = random.Next(30, 90),
                Condition = conditions[conditionIndex],
                Description = descriptions[conditionIndex],
                WindSpeed = random.Next(0, 20),
                WindDirection = random.Next(0, 360),
                Visibility = random.Next(1000, 10000),
                AlertLevel = WeatherAlertLevel.None
            };
        }

        private List<SimpleWeatherInfo> GenerateMockForecast(string city, int days)
        {
            var forecast = new List<SimpleWeatherInfo>();
            var random = new Random();
            
            for (int i = 0; i < days; i++)
            {
                for (int h = 0; h < 24; h += 3) // 每3小时一个预报
                {
                    forecast.Add(new SimpleWeatherInfo
                    {
                        Location = city,
                        DateTime = DateTime.UtcNow.AddDays(i).AddHours(h),
                        Temperature = random.Next(-5, 30),
                        FeelsLike = random.Next(-10, 35),
                        Humidity = random.Next(40, 85),
                        Condition = "Clouds",
                        Description = "多云",
                        WindSpeed = random.Next(0, 15),
                        WindDirection = random.Next(0, 360),
                        Precipitation = random.NextDouble() * 0.5,
                        Visibility = random.Next(2000, 10000)
                    });
                }
            }
            
            return forecast;
        }

        private WeatherAlertLevel DetermineAlertLevel(CurrentWeatherResponse response)
        {
            // 简单的预警级别判断逻辑
            var temp = response.Main?.Temp ?? 0;
            var windSpeed = response.Wind?.Speed ?? 0;
            var humidity = response.Main?.Humidity ?? 0;

            if (temp < -20 || temp > 40 || windSpeed > 15)
                return WeatherAlertLevel.High;
            if (temp < -10 || temp > 35 || windSpeed > 10 || humidity > 90)
                return WeatherAlertLevel.Medium;
            if (temp < 0 || temp > 30 || windSpeed > 5)
                return WeatherAlertLevel.Low;

            return WeatherAlertLevel.None;
        }

        private List<WeatherAlert> AnalyzeCurrentWeatherAlerts(SimpleWeatherInfo weather)
        {
            var alerts = new List<WeatherAlert>();

            // 温度预警
            if (weather.Temperature < -10)
            {
                alerts.Add(new WeatherAlert
                {
                    Level = WeatherAlertLevel.High,
                    Title = "低温预警",
                    Description = $"当前温度 {weather.Temperature}°C，可能影响设备正常运行",
                    ImpactTypes = new List<WeatherImpactType> { WeatherImpactType.Equipment, WeatherImpactType.Production },
                    Recommendations = new List<string> { "检查设备防冻措施", "调整生产计划", "加强设备巡检" },
                    ValidFrom = DateTime.UtcNow,
                    ValidTo = DateTime.UtcNow.AddHours(6),
                    Location = weather.Location
                });
            }

            // 风速预警
            if (weather.WindSpeed > 10)
            {
                alerts.Add(new WeatherAlert
                {
                    Level = WeatherAlertLevel.Medium,
                    Title = "大风预警",
                    Description = $"当前风速 {weather.WindSpeed} m/s，可能影响户外作业和运输",
                    ImpactTypes = new List<WeatherImpactType> { WeatherImpactType.Safety, WeatherImpactType.Transportation },
                    Recommendations = new List<string> { "暂停高空作业", "检查户外设备固定", "调整运输计划" },
                    ValidFrom = DateTime.UtcNow,
                    ValidTo = DateTime.UtcNow.AddHours(4),
                    Location = weather.Location
                });
            }

            return alerts;
        }

        private List<WeatherAlert> AnalyzeForecastAlerts(List<SimpleWeatherInfo> forecast)
        {
            var alerts = new List<WeatherAlert>();

            // 分析未来24小时的天气趋势
            var next24Hours = forecast.Where(f => f.DateTime <= DateTime.UtcNow.AddHours(24)).ToList();
            
            if (next24Hours.Any(f => f.Precipitation > 0.5))
            {
                alerts.Add(new WeatherAlert
                {
                    Level = WeatherAlertLevel.Medium,
                    Title = "降雨预警",
                    Description = "未来24小时内可能有较强降雨",
                    ImpactTypes = new List<WeatherImpactType> { WeatherImpactType.Transportation, WeatherImpactType.Safety },
                    Recommendations = new List<string> { "检查排水系统", "准备防雨措施", "调整户外作业计划" },
                    ValidFrom = DateTime.UtcNow,
                    ValidTo = DateTime.UtcNow.AddHours(24),
                    Location = next24Hours.FirstOrDefault()?.Location ?? "Unknown"
                });
            }

            return alerts;
        }

        #endregion
    }
}
